package com.qms.tubu.widget;

import android.content.Context;
import android.graphics.Rect;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewConfigurationCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.Scroller;

/**
 * Created by Mad on 2015/7/4.
 */
public class SuperScrollView extends FrameLayout{
    private ViewPager contentView;
    private View headerView;
    private int scrollRange;
    private int scrollY;
    private OnScrollListener onScrollListener;
    private int rangeOffset;
    private View currCanScrollView;
    private int mTouchSlop;
    private int minVelocity;
    private int maxVelocity;
    private Scroller mScroller;
    private VelocityTracker mVelocityTracker;
    public SuperScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        final ViewConfiguration configuration = ViewConfiguration.get(context);
        mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
        minVelocity=configuration.getScaledMinimumFlingVelocity();
        maxVelocity=configuration.getScaledMaximumFlingVelocity();
        mScroller=new Scroller(context);
    }

    @Override
    protected void onFinishInflate() {
        headerView=  getChildAt(0);
        headerView.setClickable(true);
        contentView= (ViewPager) getChildAt(1);
    }

    public void setCurrCanScrollView(View currCanScrollView) {
        this.currCanScrollView = currCanScrollView;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        scrollRange=headerView.getMeasuredHeight()-rangeOffset;
    }
    public void setRangeOffset(int offset)
    {
        rangeOffset=offset;
        if(headerView!=null && headerView.getMeasuredHeight()!=0)
        {
            scrollRange=headerView.getMeasuredHeight()-offset;
        }
    }

//    @Override
//    public boolean dispatchTouchEvent(MotionEvent ev) {
//        return super.dispatchTouchEvent(ev);
//    }
    float lastX,lastY;
    float slopX,slopY;
    boolean canIntercept;

//    @Override
//    public boolean onInterceptTouchEvent(MotionEvent ev) {
//        return super.onInterceptTouchEvent(ev);
//    }
    private boolean isMoveVer;
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int action=ev.getAction();

        switch (action)
        {
            case MotionEvent.ACTION_DOWN:
                if(!mScroller.isFinished())
                    mScroller.forceFinished(true);

                lastX=ev.getX();
                lastY=ev.getY();
                slopX=0;
                slopY=0;
                canIntercept=false;
                isMoveVer=true;
                break;
            case MotionEvent.ACTION_MOVE:
                if(!isMoveVer)
                    break;
                float dx=ev.getX()-lastX;
                float dy=ev.getY()-lastY;
                slopX+=dx;
                slopY+=dy;
                lastX=ev.getX();
                lastY=ev.getY();
                if(!canIntercept) {
                    if (Math.abs(slopX) > mTouchSlop || Math.abs(slopY)>mTouchSlop) {
                        canIntercept = true;
                        if(Math.abs(slopX)>Math.abs(slopY))
                            isMoveVer=false;
                        else
                            isMoveVer=true;
                    }

                }
                else
                {
                    boolean canScroll=canScroll(dy);
                //    Log.e("canScroll",canScroll+" "+dy);
                    if(!canScroll)
                        break;
                    if(!isTouchContent(ev)) {
                        obtainVelocityTracker(ev);
                        movePosition(dy);
                        return true;
                    }
                    ViewGroup viewGroup= (ViewGroup) contentView.getChildAt(contentView.getCurrentItem());
                    if(viewGroup==null)
                        break;
                    currCanScrollView=viewGroup.getChildAt(0);
                    boolean canVertically=currCanScrollView.canScrollVertically(-1);
                 //   Log.e("canVertically",canVertically+" "+dy);
                    if(dy>0 && canVertically)
                        break;

    //                    if(dy<0 && !currCanScrollView.canScrollVertically(-1))
    //                        break;
                    obtainVelocityTracker(ev);
                    movePosition(dy);
                    return true;
            }

            case MotionEvent.ACTION_UP:
                final VelocityTracker velocityTracker = mVelocityTracker;
                if(velocityTracker==null)
                    break;
                velocityTracker.computeCurrentVelocity(1000, maxVelocity);
                int initialVelocity = (int) velocityTracker.getYVelocity();
                if ((Math.abs(initialVelocity) > minVelocity) && getChildCount() > 0) {
                    mScroller.fling(0, scrollY, 0, -initialVelocity/2, 0, 0, 0, scrollRange);
                    invalidate();
                }
            case MotionEvent.ACTION_CANCEL:
                releaseVelocityTracker();
                break;

        }
        return super.dispatchTouchEvent(ev);
    }
    private void obtainVelocityTracker(MotionEvent event) {

        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(event);

    }
    private void releaseVelocityTracker() {
        if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
            mVelocityTracker = null;
        }

    }
//    boolean hasTouchGet;
//    private float touchY;
//    @Override
//    public boolean onTouchEvent(MotionEvent event) {
//        Log.e("hasTouchGet",hasTouchGet+"");
//        if(hasTouchGet)
//        {
//            float dy=event.getY()-touchY;
//            touchY=event.getY();
//            if(!isTouchContent(event))
//               movePosition(dy);
//            else
//            {
//                boolean canScroll=canScroll(dy);
//                currCanScrollView=((ViewGroup) contentView.getChildAt(contentView.getCurrentItem())).getChildAt(0);
//                if(!canScroll || (dy>0 && currCanScrollView.canScrollVertically(-1))) {
//                    currCanScrollView.scrollBy(0, (int) dy);
//                    hasTouchGet=false;
//                }
//                else
//                {
//                    movePosition(dy);
//                }
//            }
//        }
//        else
//        {
//            touchY=event.getY();
//            hasTouchGet=true;
//        }
//        if(event.getAction()==MotionEvent.ACTION_CANCEL || event.getAction()==MotionEvent.ACTION_UP)
//        {
//            hasTouchGet=false;
//        }
//        return true;
//    }

    @Override
    public void computeScroll() {
       if(mScroller.isFinished() || !mScroller.computeScrollOffset())
           return;
        //int dy=scrollY-mScroller.getCurrY();
        scrollY=mScroller.getCurrY();
        requestLayout();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

        if(scrollY>scrollRange)
            scrollY=scrollRange;
        int headTop=-scrollY;
        int headBottom=headTop+headerView.getMeasuredHeight();
        headerView.layout(left, headTop, right, headBottom);
        int contentTop=headBottom;
        int contentBottom=contentTop+contentView.getMeasuredHeight();
        contentView.layout(left, contentTop, right, contentBottom);
    }
    public boolean movePosition(float dy)
    {
        if(!canScroll(dy))
            return false;
        int originalScrollY=scrollY;
        scrollY= (int) (scrollY-dy);
        if(scrollY<0)
            scrollY=0;
        if(scrollY>scrollRange)
            scrollY=scrollRange;
        int offset=originalScrollY-scrollY;
        if(onScrollListener!=null)
            onScrollListener.onScroll(scrollY);
        headerView.offsetTopAndBottom(offset);
        contentView.offsetTopAndBottom(offset);
        invalidate();
        return true;
    }
    private boolean canScroll(float dy)
    {
        if((scrollY==0 && dy>0) || (scrollY==scrollRange && dy<0)) {
            return false;
        }
        return true;
    }

    public boolean isTouchContent(MotionEvent ev)
    {
        Rect rect=new Rect();
        contentView.getGlobalVisibleRect(rect);
        return rect.contains((int) ev.getX(), (int) ev.getY());
    }
    public void setOnScrollListener(OnScrollListener onScrollListener) {
        this.onScrollListener = onScrollListener;
    }

    //    private boolean sendDownEvent(MotionEvent ev) {
//        final MotionEvent last = ev;
//        MotionEvent e = MotionEvent.obtain(last.getDownTime(), last.getEventTime(), MotionEvent.ACTION_DOWN, last.getX(), last.getY(), last.getMetaState());
//        return super.dispatchTouchEvent(last);
//    }

    public interface OnScrollListener
    {
        void onScroll(int scrollY);
    }
}
